#ifndef __INCLUDED_EVEREST_DBC_DBC_H
#define __INCLUDED_EVEREST_DBC_DBC_H

#include <everest/basedef.h>


#define EVEREST_ODBC_SUCCESS(ret) (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)

BEGIN_NAMESPACE_EVEREST

namespace dbc
{
	struct IConnection;
	struct IStatement;
	struct IResultSet;
	struct IPreparedStatement;

	enum CursorType {
		CURSOR_FORWARD_ONLY = 0,
		CURSOR_STATIC       = 1,
		CURSOR_DYNAMIC      = 2,
		CURSOR_KEYSET       = 3
	};

	enum ValueType {
		VT_NULL      = 0,
		VT_INT       = 1,
		VT_BIGINT    = 2,
		VT_FLOAT     = 3,
		VT_DOUBLE    = 4,
		VT_STRING    = 5,
		VT_TIMESTAMP = 6,
		VT_BINARY    = 10
	};

	enum ParamInOutType {
		PARAM_INOUT_UNKNOWN = 0,
		PARAM_IN  = 1,
		PARAM_OUT = 2,
		PARAM_IN_OUT = 3
	};

	struct IConnection
	{
		EVEREST_INTERFACE(IConnection)

		virtual void release()  = 0;
		virtual bool close()    = 0;
		virtual void setAutoCommit(bool bAutoCommit) = 0;
		virtual bool getAutoCommit() const = 0;
		virtual void commit()   = 0;
		virtual void rollback() = 0;
		virtual bool isClosed() const = 0;
		virtual IStatement * createStatement() = 0;
		virtual IPreparedStatement * prepareStatement(const char *pstrSql) = 0;
	};

	struct IStatement
	{
		EVEREST_INTERFACE(IStatement)

		enum {
			EXEC_HAS_DATA    = 1,    // has result set or update count returned
			EXEC_NO_DATA     = 0,    // no result set returned, no record updated/inserted/deleted
			EXEC_FAIL        = -1,   // sql statement execution failed
			EXEC_UNKNOWN     = -2,   // unknown result
			EXEC_NEED_DATA   = -10,  // parameter values should be provided in next cal
			EXEC_STILL       = -11,  // statement still executing in async
			EXEC_PARAM_AVAIL = -12
		};

		virtual void addBatch(const char *pszSql) = 0;
		virtual void cancel() = 0;
		virtual void clearBatch() = 0;
		virtual void close() = 0;
		virtual int  execute(const char *pszSql) = 0;
		virtual void executeBatch(NS_EVEREST::IntVector& results) = 0;
		virtual IResultSet * executeQuery(const char * pszSql) = 0;
		virtual int  executeUpdate(const char * pszSql)  = 0;
		virtual IConnection * getConnection() const = 0;
		virtual int  getQueryTimeout() const = 0;
		virtual IResultSet * getResultSet() const = 0;
		virtual int  getUpdateCount() const = 0;
		virtual bool isClosed() const = 0;
		virtual void release() = 0;
		virtual void setQueryTimeout(int seconds) = 0;
		virtual bool getCursorScrollable() const = 0;
		virtual void setCursorScrollable(bool scrollable) = 0;
		virtual CursorType getCursorType() const = 0;
		virtual void setCursorType(CursorType cursorType) = 0;
		virtual void closeCursor() = 0;
	};

	struct IParameter
	{
		EVEREST_INTERFACE(IParameter)

		virtual ValueType getParamType() const = 0;
	};

	struct IPreparedStatement : virtual IStatement
	{
		EVEREST_INTERFACE(IPreparedStatement)

		virtual void clearParameters() = 0;
		virtual void execute() = 0;
		virtual IResultSet * executeQuery() = 0;
		virtual int  executeUpdate() = 0;
		virtual IParameter * createParameter(ValueType vt, ParamInOutType inout, size_t colsize, int decimalDigits) = 0;
		virtual bool addParameter(IParameter *pParam) = 0;
	};

	struct IResultSet
	{
		EVEREST_INTERFACE(IResultSet)

		virtual void release() = 0;
		virtual void close() = 0;
		virtual bool first() = 0;
		virtual bool last() = 0;
		virtual bool next() = 0;
		virtual bool previous() = 0;
		virtual bool absolute(ssize_t row) = 0;
		virtual bool relative(ssize_t rows) = 0;

		virtual bool   getByte(int col, char& val) const = 0;
		virtual bool   getShort(int col, short& val) const = 0;
		virtual bool   getInt(int col, int& val) const  = 0;
		virtual bool   getInt64(int col, int64_t& val) const = 0;
		virtual bool   getFloat(int col, float& val) const = 0;
		virtual bool   getDouble(int col, double& val) const = 0;
		virtual bool   getString(int col, String& str) const = 0;
		virtual bool   getBinary(int col, ByteVector& bytes) const  = 0;
		virtual bool   getDateTime(int col, DateTime& dt) const = 0;
		virtual bool   getTimestamp(int col, Timestamp& timestamp) const = 0;
	};

	struct IException
	{
		EVEREST_INTERFACE(IException)

		virtual int    code() const = 0;
		virtual String state() const = 0;
		virtual String message() const = 0;
		virtual String source() const = 0;
	};

} // end of namespace dbc

END_NAMESPACE_EVEREST


#endif // __INCLUDED_EVEREST_DBC_H

